﻿using System;
using System.Globalization;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Phone.Shell;
using System.Xml;
using System.Reflection;
using JigLibX.Physics;
using JigLibX.Collision;
using Services;
using Utilities.Menu.UIElements;
using Utilities.Menu;
using System.Collections.ObjectModel;
using TrenitaliaWP7.Resources;
using Services.Menu;
using Utilities;
using System.Windows;

namespace TrenitaliaWP7
{
    public class StateManager : AStateManager
    {

        public static Byte[] Crack_Hash = { 169, 76, 202, 205, 35, 98, 94, 154, 88, 163, 165, 159, 28, 113, 173, 197, 220, 111, 166, 108, 105, 241, 39, 176, 54, 219, 197, 79, 66, 9, 239, 176 };
        public static readonly float TRIAL_VELOCITY = 1;
        Game game;
        public bool isTrial;
        public GraphicsDeviceManager graphics;
        public OptionsState OptionsState;
        public MainMenu mainMenu;
        ResultMenu resultMenu;
        DetailsMenu detailsMenu;
        OptionsMenu optionsMenu;
        bool isReactivated = false;
        public Favorites Favorites;
        public StationsPositions Stations;
        public List<SavedResults> SavedResults;
        public List<Services.Menu.ShortCut> ShortCuts;
        public StateManager(Game game, GraphicsDeviceManager graphics)
            : base(game, graphics)
        {
            this.game = game;
            this.graphics = graphics;

            isTrial = Guide.IsTrialMode;
            //isTrial = true;

            OptionsState = Storage.GetOptionsState();
            //OptionsState.isCracked = ;
            MyButton.ALLOW_VIBRATE = OptionsState.feedback;
            if (isTrial)
            {
                if (Storage.CheckSavedCrack())
                    isTrial = false;
                else
                    Storage.DeleteCrackFile();
                OptionsState.feedback = false;
                OptionsState.suggestionKeyboard = false;
                
                
            }
            if (!OptionsState.feedback)
                MyButton.ALLOW_VIBRATE = false;
            if (isTrial)
            //{
                OptionsState.AllowGPS = false;
            //    Favorites = new TrenitaliaWP7.Favorites();
            //}
            //else
                Favorites = Storage.LoadFavorites();
            Stations = new StationsPositions();
            if (OptionsState.suggestionKeyboard)
                Stations.LoadStations();
            if (isTrial)
                ShortCuts = new List<Services.Menu.ShortCut>();
            else
            {
                ShortCuts = Storage.LoadShortCuts();
                if (ShortCuts.Count == 0)
                    Storage.BuildShortCuts(ShortCuts, Stations.Stations);
            }
            for (int i = 0; i < Stations.Stations.Count; i++)
                ShortCuts.Add(new Services.Menu.ShortCut(Stations.Stations[i].name, Stations.Stations[i].name));

            //mainMenu = new MainMenu(game);
            //resultMenu = new ResultMenu(game);
            //detailsMenu = new DetailsMenu(game);
            if (OptionsState.allowRunOffScreen)
                PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
            //if (OptionsState.AllowGPS)
            //    LoadStations();
            SavedResults = new List<SavedResults>();
#warning CARICAMENTO RICERCHE SALVATE COMMENTATO
            //new Thread(new ThreadStart(() =>
            //    {
            //        SavedResults = Storage.LoadSavedResults();
            //    })).Start();
        }
        //public void LoadStations()
        //{
        //    new Thread(new ThreadStart(() =>
        //    {
        //        Stations.LoadStations();
        //    })).Start();
        //}
        public void RebuildShortCuts()
        {
            Storage.DeleteShortCuts();
            Storage.BuildShortCuts(ShortCuts, Stations.Stations);
            for (int i = 0; i < Stations.Stations.Count; i++)
                ShortCuts.Add(new Services.Menu.ShortCut(Stations.Stations[i].name, Stations.Stations[i].name));
        }

        public override void SelectMainMenu()
        {

            if (!isReactivated)
            {
                if(mainMenu==null)
                    mainMenu = new MainMenu(game);
                if (!game.Components.Contains(detailsMenu))
                    mainMenu.openedFavourites = false;
                game.Components.Clear();
                game.Components.Add(mainMenu);
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            else
                isReactivated = false;
        }
        public void SelectMainMenu2()
        {
                if (mainMenu == null)
                    mainMenu = new MainMenu(game);
                if (!game.Components.Contains(detailsMenu))
                    mainMenu.openedFavourites = false;
                game.Components.Clear();
                game.Components.Add(mainMenu);

        }
        public void OpenAdvertisementsComponent()
        {
            //graphics.SupportedOrientations = game.GraphicsDevice.PresentationParameters.DisplayOrientation;
            game.Components.Clear();
            isTrial = false;
            var titles = new List<GameTitle>()
                {
                    GameTitle.Dice3D,
                    GameTitle.EbookReader,
                    GameTitle.Flashlight,
                    GameTitle.Ideopuzzle,
                    GameTitle.RisikoDice,
                    GameTitle.SpaceBattle
                };

            game.Components.Add(new AdsComponent(game, titles, 6));
        }
        public void SelectOptionsMenu(bool isPrevMainMenu)
        {
            game.Components.Clear();
            optionsMenu = new OptionsMenu(game, isPrevMainMenu);
            game.Components.Add(optionsMenu);

            //GC.Collect();
            //GC.WaitForPendingFinalizers();
        }

        public void SelectCreditsMenu()
        {
            game.Components.Clear();

            game.Components.Add(new CreditsMenu(game));
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }




        public void OpenTimeSelector(Action<DateTime> closeSelector, Action abortSelector, TimeSpan defaultTimeSpan, String title)
        {
            game.Components.Add(new TimeSelectorScreen(game, closeSelector, abortSelector, defaultTimeSpan, HourSelectorType.HoursMinutes, title));
        }
        public void OpenDateSelector(Action<DateTime> closeSelector, Action abortSelector, DateTime dateTime, String title)
        {
            var months_names = new ArrayList<string>();
            var days_names = new ArrayList<string>();
            //Selector.Culture = CultureInfo.CurrentCulture;
            days_names.Add(Strings.Day_0_Sunday);
            days_names.Add(Strings.Day_1_Monday);
            days_names.Add(Strings.Day_2_Tuesday);
            days_names.Add(Strings.Day_3_Wednesday);
            days_names.Add(Strings.Day_4_Thursday);
            days_names.Add(Strings.Day_5_Friday);
            days_names.Add(Strings.Day_6_Saturday);


            months_names.Add(Strings.Month_00_January);
            months_names.Add(Strings.Month_01_February);
            months_names.Add(Strings.Month_02_March);
            months_names.Add(Strings.Month_03_April);
            months_names.Add(Strings.Month_04_May);
            months_names.Add(Strings.Month_05_June);
            months_names.Add(Strings.Month_06_July);
            months_names.Add(Strings.Month_07_August);
            months_names.Add(Strings.Month_08_September);
            months_names.Add(Strings.Month_09_October);
            months_names.Add(Strings.Month_10_November);
            months_names.Add(Strings.Month_11_December);

            game.Components.Add(new DateSelectorScreen(game, closeSelector, abortSelector, dateTime, DateSelectorType.YearsMouthsDays, title, months_names, days_names));
        }


        public void OpenItemListComponent(Action<String> closeSelector, Action abortSelector, String title, ArrayList<string> itemList, String defaultString, string keyTitle, string keyDesc, bool setEmptyTextArea, string editableString)
        {//a
            game.Components.Add(new ItemsListComponent(game, closeSelector, abortSelector, title, itemList, defaultString, keyTitle, keyDesc, TextPos.Center, setEmptyTextArea, editableString, OptionsState.suggestionKeyboard, ShortCuts));
        }

        public void OpenItemListComponent(Action<String> closeSelector, Action abortSelector, String title, ArrayList<string> itemList, String defaultString, string keyTitle, string keyDesc, bool setEmptyTextArea, string editableString, string text2)
        {//a
            game.Components.Add(new ItemsListComponent(game, closeSelector, abortSelector, title, itemList, defaultString, keyTitle, keyDesc, TextPos.Center, setEmptyTextArea, editableString, text2, OptionsState.suggestionKeyboard, ShortCuts));
        }

        public void OpenItemListComponent(Action<String> closeSelector, Action abortSelector, String title, ArrayList<string> itemList)
        {
            game.Components.Add(new ItemsListComponent(game, closeSelector, abortSelector, title, itemList, TextPos.Center));
        }
        public void OpenItemListComponent(Action<String> closeSelector, Action abortSelector, String title, ArrayList<string> itemList,
            ArrayList<String> itemsList2, SpriteFont font)
        {
            game.Components.Add(new ItemsListComponent(game, closeSelector, abortSelector, title, itemList, itemsList2, TextPos.Left, TextPos.Left, font));
        }
        public void OpenEditListComponent(Action<String> EditItem, Action abortSelector, String title, ArrayList<string> itemList, String confirmString)
        {
            game.Components.Add(new ItemsListComponent(game, title, itemList, confirmString, EditItem, abortSelector, TextPos.Center));
        }
        public void OpenEditListComponent(Action<String> EditItem, Action abortSelector, String title, ArrayList<string> itemList, ArrayList<string> itemList2, String confirmString, SpriteFont font)
        {
            game.Components.Add(new ItemsListComponent(game, title, itemList, itemList2, confirmString, EditItem, abortSelector, TextPos.Left, TextPos.Left, font));
        }
        //public void OpenErrorPopUp(Action close, string desc, string item, SpriteFont font, Texture2D confirm, Texture2D circle, Texture2D bg, Color bgcolor)
        //{
        //    game.Components.Add(new PopUpComponent(game, close, desc, item, font, confirm, circle, bg, bgcolor));
        //}
        public void OpenNotifyPopUp(string s)
        {
            MessageBox.Show(s);
        }
        public bool OpenQuestionPopUp(string s)
        {
            return OpenQuestionPopUp(s, "");
        }
        public bool OpenQuestionPopUp(string s, string title)
        {
            if (MessageBox.Show(s, "", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                return true;
            return false;
        }
        public void OpenResultMenu(Result result)
        {
            mainMenu.Enabled = false;
            game.Components.Clear();
            //game.Components.Remove(mainMenu);
            //resultMenu = new ResultMenu(game, result);
            OptionsState.showAllSolutions = false;
            if (resultMenu == null)
                resultMenu = new ResultMenu(game, result);
            else
                resultMenu.SetResult(result);
            resultMenu.searchAllSolutions = false;
            game.Components.Add(resultMenu);
        }
        public void OpenResultMenu()
        {
            if (resultMenu != null)
            {
                game.Components.Clear();
                game.Components.Add(resultMenu);
            }
            else
                SelectMainMenu();
        }
        public void OpenDetailsMenu(Details chosen, bool isFavorite)
        {
            game.Components.Clear();
            detailsMenu = new DetailsMenu(game, chosen, isFavorite);
            game.Components.Add(detailsMenu);
        }
        public void ReOpenDetailsMenu()
        {
            if (detailsMenu != null)
            {
                game.Components.Clear();
                game.Components.Add(detailsMenu);
            }
        }
        //public void OpenPopUp(Action confirm, Action cancel, string desc, string item, string yes, string no, SpriteFont font, Texture2D box, Texture2D bg, Color bgcolor)
        //{
        //    game.Components.Add(new PopUpComponent(game, confirm, cancel, desc, item, yes, no, font, box, bg, bgcolor));
        //}

        public SavedState BuildSavedState()
        {
            SavedState state = new SavedState();

            if (detailsMenu != null && game.Components.Contains(detailsMenu) || (game.Components.Contains(optionsMenu) && !optionsMenu.isPrevMainMenu))
            {

                state.trains = detailsMenu.trains;
                state.chosen = detailsMenu.chosen;
                state.isPrevMainMenu = detailsMenu.isPrevMainMenu;
                state.rows_offset = detailsMenu.getRowsOffset();
                if (resultMenu != null)
                {
                    state.results = resultMenu.results;
                    state.current_result = resultMenu.current_result;
                    state.searchAllSolutions = resultMenu.searchAllSolutions;
                    state.originalQuery = resultMenu.originalQuery;
                    state.originalBuyQuery = resultMenu.originalBuyQuery;
                }
                if (mainMenu != null)
                {
                    state.dateTime = mainMenu.dateTime;
                    state.from = mainMenu.from;
                    state.to = mainMenu.to;
                    state.openedFavourites = mainMenu.openedFavourites;
                }
            }
            else if (resultMenu != null && game.Components.Contains(resultMenu))
            {
                state.results = resultMenu.results;
                state.current_result = resultMenu.current_result;
                state.searchAllSolutions = resultMenu.searchAllSolutions;
                state.originalQuery = resultMenu.originalQuery;
                state.originalBuyQuery = resultMenu.originalBuyQuery;
                if (mainMenu != null)
                {
                    state.dateTime = mainMenu.dateTime;
                    state.from = mainMenu.from;
                    state.to = mainMenu.to;
                    state.openedFavourites = mainMenu.openedFavourites;
                }
            }
            //else if (mainMenuSaved && game.Components.Contains(mainMenu))
            //{
            //    state.dateTime = mainMenu.dateTime;
            //    state.from = mainMenu.from;
            //    state.to = mainMenu.to;
            //}
            return state;
        }
        public SavedState BuildCompleteSavedState()
        {
            SavedState state = new SavedState();

            if (detailsMenu != null)
            {

                state.trains = detailsMenu.trains;
                state.chosen = detailsMenu.chosen;
                state.isPrevMainMenu = detailsMenu.isPrevMainMenu;
                state.rows_offset = detailsMenu.getRowsOffset();
            }
            if (resultMenu != null)
            {
                state.results = resultMenu.results;
                state.current_result = resultMenu.current_result;
                state.searchAllSolutions = resultMenu.searchAllSolutions;
                state.originalQuery = resultMenu.originalQuery;
                state.originalBuyQuery = resultMenu.originalBuyQuery;
            }
            if (mainMenu!=null)
            {
                state.dateTime = mainMenu.dateTime;
                state.from = mainMenu.from;
                state.to = mainMenu.to;
                state.openedFavourites = mainMenu.openedFavourites;
            }
            return state;
        }
        //public SavedState BuildSavedState()
        //{
        //    return BuildSavedState(false);
        //}

        public void Deactivate()
        {
            //if (isTrial)
            //    return;
            //SavedState state = new SavedState();

            //if (detailsMenu!=null && game.Components.Contains(detailsMenu) || (game.Components.Contains(optionsMenu) && !optionsMenu.isPrevMainMenu))
            //{
                
            //    state.trains = detailsMenu.trains;
            //    state.chosen = detailsMenu.chosen;
            //    state.isPrevMainMenu = detailsMenu.isPrevMainMenu;
            //    if (resultMenu != null)
            //    {
            //        state.results = resultMenu.results;
            //        state.current_result = resultMenu.current_result;
            //    }
            //    if (mainMenu != null)
            //    {
            //        state.dateTime = mainMenu.dateTime;
            //        state.from = mainMenu.from;
            //        state.to = mainMenu.to;
            //    }
            //}
            //else if (resultMenu!=null && game.Components.Contains(resultMenu))
            //{
            //    state.results = resultMenu.results;
            //    state.current_result = resultMenu.current_result;
            //    if (mainMenu != null)
            //    {
            //        state.dateTime = mainMenu.dateTime;
            //        state.from = mainMenu.from;
            //        state.to = mainMenu.to;
            //    }
            //}
            ////else if (game.Components.Contains(mainMenu))
            ////{
            ////    state.dateTime = mainMenu.dateTime;
            ////    state.from = mainMenu.from;
            ////    state.to = mainMenu.to;
            ////}

            SavedState state = BuildSavedState();

            //if (Microsoft.Phone.Shell.PhoneApplicationService.Current.State.ContainsKey("InformaTreni"))
                Microsoft.Phone.Shell.PhoneApplicationService.Current.State.Remove("InformaTreni");
            Microsoft.Phone.Shell.PhoneApplicationService.Current.State.Add("InformaTreni", state);
            //Storage.SaveSavedState(state);
        }
        public void Activate()
        {
            //if (OptionsState.allowRunOffScreen)
            //    return;
            //
            //if (isTrial)
                //return;
            isReactivated = true;
            //SavedState state = Storage.LoadSavedState();
            object state_o;
            bool ok = Microsoft.Phone.Shell.PhoneApplicationService.Current.State.TryGetValue("InformaTreni", out state_o);
            if (!ok)
            {
                isReactivated = false;
                return;
            }
            try
            {
                SavedState state = (SavedState)state_o;
                if (state.trains.Count != 0)
                {
                    //mainMenu = new MainMenu(game);
                    resultMenu = new ResultMenu(game);
                    detailsMenu = new DetailsMenu(game);
                    game.Components.Clear();
                    detailsMenu.trains = state.trains;
                    detailsMenu.chosen = state.chosen;
                    detailsMenu.isPrevMainMenu = state.isPrevMainMenu;
                    
                    resultMenu.current_result = state.current_result;
                    resultMenu.results = state.results;
                    resultMenu.searchAllSolutions = state.searchAllSolutions;
                    resultMenu.prev_searchAllSolutions = state.searchAllSolutions;
                    resultMenu.originalBuyQuery = state.originalBuyQuery;
                    resultMenu.originalQuery = state.originalQuery;
                    //mainMenu.to = state.to;
                    //mainMenu.from = state.from;
                    //mainMenu.dateTime = state.dateTime;
                    mainMenu = new MainMenu(game, state.dateTime, state.from, state.to);
                    mainMenu.openedFavourites = state.openedFavourites;
                    game.Components.Add(detailsMenu);
                    detailsMenu.setRowsOffset(state.rows_offset);
                }
                else if (state.results.Count != 0)
                {
                    game.Components.Clear();
                    resultMenu = new ResultMenu(game);
                    resultMenu.current_result = state.current_result;
                    resultMenu.results = state.results;
                    resultMenu.searchAllSolutions = state.searchAllSolutions;
                    resultMenu.prev_searchAllSolutions = state.searchAllSolutions;
                    resultMenu.originalBuyQuery = state.originalBuyQuery;
                    resultMenu.originalQuery = state.originalQuery;
                    mainMenu = new MainMenu(game, state.dateTime, state.from, state.to);
                    mainMenu.openedFavourites = state.openedFavourites;
                    game.Components.Add(resultMenu);
                    resultMenu.searchAllSolutions = state.searchAllSolutions;
                }
                else
                    isReactivated = false;
                 mainMenu.openedFavourites = state.openedFavourites;
                //else
                //{
                //    mainMenu = new MainMenu(game, state.dateTime, state.from, state.to);
                //    game.Components.Add(mainMenu);
                //}
            }
            catch (Exception e)
            {
                e.ToString();
                isReactivated = false;
            }
            finally
            {

                Microsoft.Phone.Shell.PhoneApplicationService.Current.State.Remove("InformaTreni");
            }
        }
        public void StartVibration(TimeSpan duration)
        {
            Microsoft.Devices.VibrateController.Default.Start(duration);
        }
    }

}